package com.gfeeling.dao.impl;

import java.io.Serializable;
import java.util.List;
import java.util.Map;

import org.hibernate.Query;
import org.hibernate.SQLQuery;
import org.hibernate.Session;
import org.hibernate.SessionFactory;
import org.hibernate.transform.Transformers;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Repository;

import com.gfeeling.dao.BaseDao;
import com.gfeeling.model.PageBean;
import com.gfeeling.utils.QueryHelper;

@Repository
@SuppressWarnings({ "unchecked", "rawtypes" })
public class BaseDaoImpl<T> implements BaseDao<T> {
    @Autowired
    private SessionFactory sessionFactory;

	/**
	 * 获得当前事物的session
	 * 
	 * @return org.hibernate.Session
	 */
	public Session getCurrentSession() {
		return sessionFactory.getCurrentSession();
	}
	@Override
	public String save(T o) {
		if(o!=null){
		Serializable save = getCurrentSession().save(o);
		getCurrentSession().flush();
		return save.toString();
		}
		return null;
	}

	@Override
	public void delete(T o) {
		if(o!=null){
			getCurrentSession().delete(o);
		}
	}

	@Override
	public void update(T o) {
		if(o!=null){
			getCurrentSession().update(o);
			getCurrentSession().flush();
		}
	}

	@Override
	public void saveOrUpdate(T o) {
		if(o!=null){
			getCurrentSession().saveOrUpdate(o);
			getCurrentSession().flush();
		}
	}

	@Override
	public T getById(Class<T> c, Serializable id) {
		return (T) getCurrentSession().get(c, id);
	}

	@Override
	public T getByHql(String hql) {
		Query query = getCurrentSession().createQuery(hql);
		List<T> list = query.list();
		
		if(list!=null && list.size() > 0){
			return list.get(0);
		}
		return null;
	}

	@Override
	public T getByHql(String hql, Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(hql);
		if(params != null && !params.isEmpty()){
			for (String key : params.keySet()) {
				query.setParameter(key, params.get(key));
			}
		}
		List<T> list = query.list();
		if(list != null && list.size()>0){
			return list.get(0);
		}
		return null;
	}

	@Override
	public List<T> find(String hql) {
		Query query = getCurrentSession().createQuery(hql);
		return query.list();
	}

	@Override
	public List<T> find(String hql, Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(hql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				query.setParameter(key, params.get(key));
			}
		}
		return query.list();
	}

	@Override
	public List<T> find(String hql, int pageNo, int pageSize) {
		Query query = getCurrentSession().createQuery(hql);
		return query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
	}

	@Override
	public List<T> find(String hql, Map<String, Object> params, int pageNo,
			int pageSize) {
		Query query = getCurrentSession().createQuery(hql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				query.setParameter(key, params.get(key));
			}
		}
		return query.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).list();
	}

	@Override
	public Long count(String hql) {
		Query query = getCurrentSession().createQuery(hql);
		return (Long) query.uniqueResult();
	}

	@Override
	public Long count(String hql, Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(hql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				query.setParameter(key, params.get(key));
			}
		}
		return (Long) query.uniqueResult();
	}

	@Override
	public int executeHql(String hql) {
		Query query = getCurrentSession().createQuery(hql);
		return query.executeUpdate();
	}

	@Override
	public int executeHql(String hql, Map<String, Object> params) {
		Query query = getCurrentSession().createQuery(hql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				query.setParameter(key, params.get(key));
			}
		}
		return query.executeUpdate();
	}

	@Override
	public List<Map> findBySql(String sql) {
		SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
		return sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
	}

	@Override
	public List<Map> findBySql(String sql, int pageNo, int pageSize) {
		SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
		return sqlQuery.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
	}

	@Override
	public List<Map> findBySql(String sql, Map<String, Object> params) {
		SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				sqlQuery.setParameter(key, params.get(key));
			}
		}
		return sqlQuery.setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
	}

	@Override
	public List<Map> findBySql(String sql, Map<String, Object> params,
			int pageNo, int pageSize) {
		SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				sqlQuery.setParameter(key, params.get(key));
			}
		}
		return sqlQuery.setFirstResult((pageNo - 1) * pageSize).setMaxResults(pageSize).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP).list();
	}

	@Override
	public int executeSql(String sql) {
		SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
		return sqlQuery.executeUpdate();
	}

	@Override
	public int executeSql(String sql, Map<String, Object> params) {
		SQLQuery sqlQuery = getCurrentSession().createSQLQuery(sql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				sqlQuery.setParameter(key, params.get(key));
			}
		}
		return sqlQuery.executeUpdate();
	}

	@Override
	public Long countBySql(String sql) {
		SQLQuery q = getCurrentSession().createSQLQuery(sql);
		return (Long) q.uniqueResult();
	}

	@Override
	public Long countBySql(String sql, Map<String, Object> params) {
		SQLQuery q = getCurrentSession().createSQLQuery(sql);
		if (params != null && !params.isEmpty()) {
			for (String key : params.keySet()) {
				q.setParameter(key, params.get(key));
			}
		}
		return (Long) q.uniqueResult();
	}
	@Override
	public PageBean getPageBean(int pageNum, int pageSize,
			QueryHelper queryHelper) {
		// 参数列表
		List<Object> parameters = queryHelper.getParameters();
		// 查询本页的数据列表
		Query listQuery = getCurrentSession().createQuery(queryHelper.getListQueryHql()); // 创建查询对象
		if (parameters != null) { // 设置参数
			for (int i = 0; i < parameters.size(); i++) {
				listQuery.setParameter(i, parameters.get(i));
			}
		}
		listQuery.setFirstResult((pageNum - 1) * pageSize);
		listQuery.setMaxResults(pageSize);
		List list = listQuery.list(); // 执行查询

		// 查询总记录数量
		Query countQuery = getCurrentSession().createQuery(queryHelper.getCountQueryHql());
		if (parameters != null) { // 设置参数
			for (int i = 0; i < parameters.size(); i++) {
				countQuery.setParameter(i, parameters.get(i));
			}
		}
		Long count = (Long) countQuery.uniqueResult(); // 执行查询

		return new PageBean(pageNum, pageSize, count.intValue(), list);
	}
	@Override
	public PageBean getPageBean(QueryHelper queryHelper) {
		// 参数列表
				List<Object> parameters = queryHelper.getParameters();
				// 查询本页的数据列表
				Query listQuery = getCurrentSession().createQuery(queryHelper.getListQueryHql()); // 创建查询对象
				if (parameters != null) { // 设置参数
					for (int i = 0; i < parameters.size(); i++) {
						listQuery.setParameter(i, parameters.get(i));
					}
				}
				List list = listQuery.list(); // 执行查询
				return new PageBean(list);
	}

}
